在 JS 中我們是利用 if(condition){statement1}else{statement2}
來設定條件並決定執行哪一段陳述式(statement),如果 condition
為 truthy
就執行 statement1
,否則就執行 statement2
。
但在 Vue 裡可以利用 v-if
、 v-else-if
、 v-else
指令快速設定條件,並決定執行哪段 HTML 元素。
v-if
指令僅有 v-if
<!--v-if="條件式(condition)"-->
<!--成立即顯示-->
<h1 v-if="awesome">Vue is awesome!</h1>
<script>
const vm = new Vue({
el:'#vm',
data:{
// 可以利用 truthy 或 falsy 來決定條件是否成立
awesome: 0,
}
})
</script>
成立時,畫面上即會顯示該元素,如果不成立,打開 Chrome 開發工具會發現一個佔位標籤 <!---->
。
有 v-if
、 v-else-if
跟 v-else
<h3 v-if="Num>9">First</h3>
<h3 v-else-if="Num>5">Second</h3>
<h3 v-else>Third</h3>
v-if
、 v-else-if
跟 v-else
這幾個指令要緊緊相依,中間不能插入其他的不相干的元素,另外在有 v-else
的情況下,就不會出現佔位標籤 <!---->
,這是因為在 v-if
、 v-else-if
跟 v-else
是一種切換的關係,一定會有其中一個顯示在畫面上,所以不像是單純只有 v-if
時,當 v-if
不成立時,HTML 就沒有留位置給它,所以需要靠佔位標籤 <!---->
來留位置。
template
標籤來將條件分組利用 template
標籤分組的好處是甚麼?
簡單來說就是畫面上不會出現太多的 <div>
來為要呈現的區塊分組,又或是在 HTML 使用太多的 v-if
跟 v-else
。
可以比較一下這幾種用法:
<!--第一種寫法,運用很多div-->
<div v-if="templateReveal">
<h1>利用div</h1>
<p>Paragraph 1</p>
<p>Paragraph 1</p>
</div>
<div v-else>
<h1>利用div</h1>
<p>Paragraph 2</p>
<p>Paragraph 2</p>
</div>
<!--第二種寫法,都加上v-if-->
<h1 v-if="templateReveal">全都加上v-if</h1>
<h1 v-else>全都加上v-else</h1>
<p v-if="templateReveal">Paragraph 1</p>
<p v-else>全都加上v-else</p>
<p v-if="templateReveal">Paragraph 1</p>
<p v-else>全都加上v-else</p>
<!--第三種寫法,使用template-->
<template v-if="templateReveal">
<h1>使用template</h1>
<p>Paragraph 1</p>
<p>Paragraph 1</p>
</template>
<template v-else>
<h1>使用template</h1>
<p>Paragraph 2</p>
<p>Paragraph 2</p>
</template>
第二種實在是非常麻煩,完全不用考慮,但第一種跟第三種的差別在哪裡?
使用 <template>
可以製作一個群組,但是在 HTML 上不會顯示出 <template>
標籤,使用 <div>
同樣可以做出一個群組,但是在 HTML 上會顯示出 <div>
標籤,單純只看包裹群組的的標籤是否還有額外的作用,有的話就須使用 <div>
標籤,例如為群組加上 class
樣式,如果使用 <template>
標籤的話,因為會消失,所以會導致群組無法吃到 class
樣式。
v-if
指令搭配 key
AtttributeVue 為了能快速的渲染畫面,所以在資料更改後,對於那些沒更改的資料會繼續使用,而非重新渲染,所以當我們製作群組、更動資料時,如果群組的元素幾乎是一樣的狀況下, Vue 會重複使用,而非重新渲染,這個問題在之後的 v-for
也會有。
可以參考 Vue 文件提供的例子:元素切換
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address">
</template>
在切換的過程中,輸入在 <input>
中的文字,並不會隨著 loginType
的不同而有所改變(即使切換還是存在剛剛輸入的文字)。如同上面所說的 Vue 為了快速渲染畫面,針對幾乎相同的元素模板將重複使用。
key
Atttribute 解決模板重複使用的問題為了解決上面的問題, Vue 提供了 key
Atttribute 來表達這2個元素是不同的,不要去複用。
資料切換而模板重複使用造成問題的通常是表單元素 <input>
,所以可以在 <input>
上加入 key
Atttribute 來解決複用的問題。
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
v-show
指令v-show
同樣是針對元素出現與否的指令,跟 v-if
最大的不同是在 v-show
是利用 CSS 切換 display:none
或 display:block
來決定元素是否顯示在畫面,在 DOM tree 是可以找到該元素的,而 v-if
是整盤端走,在 DOM tree 是無法找到的。
<h1 v-show="show">我是v-show</h1>
v-if
跟 v-show
的使用時機當有頻繁切換需要時,使用 v-show
,如果沒有的話,就使用 v-if
,這是因為 v-show
不論初始值是真值(Truthy)還是假值(Falsy)都一定會先渲染出來,但是 v-if
初始值如果是假值,則不會去渲染畫面,但在切換的過程則需要不斷的重建或銷毀,也因此 v-show
會有較高的初始渲染效能,而 v-if
則是在切換的過程,使用較多的效能。
Demo:[DAY06]跟 Vue.js 認識的30天 - Vue 的條件渲染
參考資料:
Vue.js-条件渲染